/*************************************************************************
        > File Name: dataitem.h
        > Author: xuwenlong
        > Mail: myxuan475@126.com
        > Created Time: 2018年02月24日 星期六 16时00分52秒
 ************************************************************************/
#ifndef LIBXCOM_DATAITEM_H
#define LIBXCOM_DATAITEM_H

#include "operator.h"
#include "opitem.h"
#include "template.h"
#include <memory>
#include <stdio.h>
#include <string>

namespace libxcom {
class Operator;
class DataItem;

class DataItem : public OpInterface {
public:
    DataItem(const std::string &name, const std::string &templ, const std::string &expr, float rate = 1.0);
    virtual ~DataItem();

    bool IsEmpty();

    /*
     * 解析表达式
     */
    void ExprToParams(const std::vector<OpValue> &params);
    void ParseDataExpr(const std::string &expr, float rate);

    void EmptyParam();
    bool PushParam(const std::string &param);
    bool PushParam(const OpValue &ov);

    // 采集
    virtual std::shared_ptr<Express> LocateFunction(const std::string &def, int funcId = -1);

    virtual OpValue GetVar(const std::string &var)
    {
        return operator_[var.c_str()];
    }
    void SetVar(const std::string &var, const OpValue &v)
    {
        operator_.SetVar(var.c_str(), v);
    }
    void SetVar(const std::string &var, const std::string &expr);
    OpValue GetResult(const std::string &expr, float rate);

    virtual OpValue Result();
    virtual TYPE_DEFINE DataType();

    OpValue FuncCall();
    OpValue RateCall(const OpValue &result, float rate);
    OpValue GenerateNext();

    RECV_RESULT ParseRecvCmd(const CmdValue &recvCmd, const std::string &func, int32_t funcId = -1);

    RECV_RESULT ParseCmd(OpValue &result, const CmdValue &recvCmd, const std::string &func, int32_t funcId = -1);

    OpValue GenerateCmd(const std::string &func);

    void ResetCmd();

private:
    static std::shared_ptr<Express> wrapExpress(const std::string &str);

    class ParamsLock {
    public:
        ParamsLock(Operator &iop_) : iop(iop_)
        {
            iop.PushStack(Operator::AUTO_PARAM);
        }
        ~ParamsLock()
        {
            iop.PopStack(Operator::AUTO_PARAM);
        }

    private:
        Operator &iop;
    };

private:
    std::string name_;
    std::vector<std::shared_ptr<Express>> listExprs_;
    std::vector<OpValue> listValues_;
    Operator operator_;
    Template template_;
    std::shared_ptr<Express> dataExpr_;
    float fRate_;
};
} // namespace libxcom
#endif
